import axios, { type AxiosInstance, type AxiosRequestConfig, type InternalAxiosRequestConfig, type AxiosHeaderValue, type AxiosResponse } from "axios";
import common from "_s/common/localstore";
import { Notify, Loading } from "quasar";
declare module "vue" {
  interface ComponentCustomProperties {
    $axios: AxiosInstance;
    $api: AxiosInstance;
  }
}

const requestMap = new Map();

const addPendingRequest = (config: AxiosRequestConfig) => {
  const requestKey = `${config.method}:${config.url}`;
  if (!requestMap.has(requestKey)) {
    config.cancelToken = new axios.CancelToken(cancel => {
      requestMap.set(requestKey, cancel);
    });
  }
};
// 从 pendingRequests 中移除请求
const removePendingRequest = (config: AxiosRequestConfig) => {
  const requestKey = `${config.method}:${config.url}`;
  if (requestMap.has(requestKey)) {
    const cancelToken = requestMap.get(requestKey);
    cancelToken(requestKey);
    requestMap.delete(requestKey);
  }
};

class HttpRquest {
  interceptors(instance: AxiosInstance, contentType: AxiosHeaderValue) {
    // 请求拦截
    instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 添加请求到 pendingRequests
        addPendingRequest(config);
        const token = common.getToken();
        config.withCredentials = true;
        config.headers["Authorization"] = token;
        config.headers["Content-Type"] = contentType;
        return config;
      },
      (error: any) => {
        return Promise.reject(error instanceof Error ? error : new Error(error.message || JSON.stringify(error)));
      }
    );
    instance.interceptors.response.use(
      (response: AxiosResponse) => {
        removePendingRequest(response.config);

        const responseType = response.request.responseType;
        if (responseType === "blob" || responseType === "arraybuffer") return response;
        const { data, status } = response;
        const { code } = data;
        if (code === 401) {
          // 执行无感刷新token
          const refreshToken = common.getRefreshToken();
          if (!refreshToken) return (window.location.href = "/#/login");

          try {
            // 刷新 token 的接口

            // common.setToken(token); // 更新token
            // common.setRefreshToken(refresh_Token); // refreshToken

            // 使用新的 token 重试原始请求

            return this.request(response.config, response.config.headers["Content-Type"]);
          } catch (e) {
            // 如果刷新 token 失败,则清除 token 并重定向到登录页面
            common.setToken("");
            common.setRefreshToken("");
            window.location.href = "/#/login";
            return Promise.reject(e instanceof Error ? e : new Error(String(e)));
          }
        }
        if (status === 200) return data;

        // Notify.create({ type: "error", message: "服务器出错请稍后再试" });
      },
      error => {
        // 从 pendingRequests 中移除请求
        removePendingRequest(error.config);
        if (error.code === "ECONNABORTED" && error.message.indexOf("timeout") !== -1) Notify.create({ type: "error", message: "请求超时请稍后再试" });
        if (Loading.isActive) Loading.hide();
        // window.location.href = "/#/errservice";
        // if (axios.isCancel(error)) {
        //   // 如果是取消请求的错误,直接返回,不再处理
        //   return Promise.reject(error instanceof Error ? error : new Error(JSON.stringify(error)));
        // }
        return Promise.reject(error instanceof Error ? error : new Error(String(error)));
      }
    );
  }
  request<T>(options: AxiosRequestConfig, contentType: AxiosHeaderValue = "application/json"): Promise<T> {
    const instance = axios.create();
    // const base: AxiosRequestConfig = {
    //   baseURL: import.meta.env.VITE_BASE_API ?? "/"
    // };
    options.responseType = options.responseType || "json"; // 响应数据格式
    options.timeout = options.timeout || 15000; // 超时时间
    if (options.method === "get") {
      options.params = options.data;
      options.data = "";
    }
    this.interceptors(instance, contentType);
    return instance(options);
  }
}

export const req = new HttpRquest();
